#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sqlite3.h>

#include "commonality.h"
#include "sqlite.h"
#include "server.h"

int main(int argc, char* argv[])
{
	if (argc != 3) {
		puts("Usage: ./server IPaddress Port.");
		exit(-1);
	}

	struct sockaddr_in serveraddr;
	struct sockaddr_in clientaddr;
	int len = sizeof(clientaddr);
	int sockfd = -1;
	int accfd = -1;
	pid_t pid = -1;
	USER user_recv;
	USER user_send;
	INFO info_send;
	sqlite3* ppDb;
	int ret = -1;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socket < 0) {
		perror("socket");
		exit(-1);
	}

	signal(SIGCHLD, SIG_IGN);// 避免僵尸进程

	serveraddr.sin_family = AF_INET;
	serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
	serveraddr.sin_port = htons(atoi(argv[2]));
	
	bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in));

	listen(sockfd, 5);

	// 打开数据库
	sqlite_open(SQLITE_NAME, &ppDb);
	// 创建账户表
	ret = sqlite_create(ppDb, ENTRY_TABLE);
	if (0 == ret) {
		// 创建默认账户
		do_insert_user(ppDb, SUPERUSER_NAME, SUPERUSER_PASSWORD, SUPERUSER_LEVEL);
	}
	
	// 创建信息表
	sqlite_create(ppDb, INFO_TABLE);
	
	while (1) {
		// 等待客户端链接
		printf("Wait for the connection....\n");
		accfd = accept(sockfd,(struct sockaddr *)&clientaddr, &len);
		if (accfd < 0) {
			perror("accept");
			exit(-1);
		}
		
		// tcp并发服务器模型
		pid = fork();
		if (pid > 0) {
			// 1
			// waitpid(-1, NULL, WNOHANG);
		} else {
			while (1) {
				debug("Connection successful....\n");
				
				memset(&user_recv, 0, sizeof(user_recv));
				memset(&user_send, 0, sizeof(user_send));
				memset(&info_send, 0, sizeof(info_send));
				// 等待接收客户端数据包
				printf("Wait for the data from client....\n");
				recv(accfd, &user_recv, sizeof(user_recv), 0);
				printf("type:%d\n",user_recv.type);
				switch(user_recv.type) {
					case USER_LOG:	// 用户登录
						ret = do_user_login(ppDb, ENTRY_TABLE, &user_recv, USER_LEVEL);
						//printf("ret =%d\n",ret);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 
					break;
					
					case ADMIN_LOG:	// 管理员登录
						//int do_user_login(ppDb, ENTRY_TABLE, &user_recv, ADMIN_LEVEL);
						ret = do_user_login(ppDb, ENTRY_TABLE, &user_recv, ADMIN_LEVEL);

						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 

					break;
					
					case ROOT_LOG:	// 超级用户登录
						//int do_user_login(ppDb, ENTRY_TABLE, &user_recv, SUPERUSER_LEVEL);
						ret = do_user_login(ppDb, ENTRY_TABLE, &user_recv, SUPERUSER_LEVEL);
						//printf("ret =%d\n",ret);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 

					break;
					
					case ADMIN_ADD_USER:	// 管理员添加用户
						//int do_register_user(ppDb, ENTRY_TABLE, &user_recv, ADMIN_LEVEL);
						do_register_user(ppDb, ENTRY_TABLE, accfd, &user_recv, ADMIN_LEVEL);
					break;
					
					case ROOT_ADD_ADMIN:	// 超级用户添加管理员
						//int do_register_user(ppDb, ENTRY_TABLE, &user_recv, SUPERUSER_LEVEL);
						do_register_user(ppDb, ENTRY_TABLE, accfd, &user_recv, SUPERUSER_LEVEL);
					break;
					
					case ADMIN_DEL:	// 管理员删除一个员工
						//int do_del_user(ppDb, user_recv.name, ADMIN_LEVEL);
						ret = do_del_user(ppDb, user_recv.name, ADMIN_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						}
					break;
					
					case ROOT_DEL_ADMIN:	// 超级用户删除管理员
						//int do_del_user(ppDb, user_recv.name, SUPERUSER_LEVEL);
						ret = do_del_user(ppDb, user_recv.name, SUPERUSER_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						}
						
					break;
					
					case USER_ALTER:	// 用户修改自己的信息
						//int do_alter_user(ppDb, INFO_TABLE, accfd, USER_LEVEL);
						ret = do_alter_user(ppDb, user_recv.name, accfd, USER_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						}
					break;
					
					case ADMIN_ALTER:	// 管理员修改所有用户的信息
						//int do_alter_user(ppDb, INFO_TABLE, accfd, ADMIN_LEVEL);
						ret = do_alter_user(ppDb, user_recv.name, accfd, ADMIN_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						}
					break;
					
					case ROOT_ALTER:	// 超级用户修改全部
						//int do_alter_user(ppDb, INFO_TABLE, accfd, SUPERUSER_LEVEL);
						ret = do_alter_user(ppDb, user_recv.name, accfd, SUPERUSER_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						}
					break;
					
					case USER_QUERY:	// 用户查询自己信息

						ret =  do_user_query(ppDb, INFO_TABLE, accfd, USER_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 

					break;
					
					case USER_QUERY_OTHER:	// 用户查看其他用户信息
			
						ret =  do_user_query(ppDb, INFO_TABLE, accfd,USER_QUERY_OTHER);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 

					break;
					
					case ADMIN_QUERY:	// 管理员查询用户信息

						ret = do_user_query(ppDb, INFO_TABLE, accfd, ADMIN_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 
					break;
					
					case ADMIN_QUERY_ALL:	// 超级用户查询用户信息
					
						ret = do_user_query(ppDb, INFO_TABLE, accfd, SUPERUSER_LEVEL);
						if (ret < 0) {
							user_send.err = -1;
						} else {
							user_send.err = 0;
						} 

					break;
					
					case CLIENT_QUIT:	// 退出
						break;
					break;
					
					default:
					break;
				}

						
				send(accfd, &user_send, sizeof(user_send), 0);

				
			}
		}
	}
	
	return 0;
}

// 登录账号
// 参数1: 登录表
// 参数2: 登录表名
// 参数3: 客户端的登录结构体
// 参数4: 当前登录用户的权限
// 返回值: 成功0 失败-1
int do_user_login(sqlite3 *ppDb, const char* table, USER* msg, int level)
{
	/* 用msg的name,password和level */
	/* 匹配数据库中的name,password和privilege */
	if(do_query_user(ppDb, msg->name, msg->password, level)){
		return -1;
	}
		
	return 0;
}

// 注册账号
// 参数1: 登录表
// 参数2: 登录表名
// 参数3: 已连接的fd
// 参数3: 要添加的用户名和密码(由客户端提供)
// 参数4: 当前登录用户的权限
// 返回值: 成功0 失败-1
int do_register_user(sqlite3* ppDb, const char* table, int accfd, USER* msg, int level)
{
	INFO info_recv;
	
	
	recv(accfd, &info_recv, sizeof(info_recv), 0);
	
	switch (level) {
		case ADMIN_LEVEL:	// 管理员添加用户
			do_insert_user(ppDb,msg->name,msg->password,USER_LEVEL);
			do_insert_user_info(ppDb,info_recv.name,info_recv.no,info_recv.addr,info_recv.age,info_recv.level,info_recv.phone,info_recv.salary);
		break;	

		case SUPERUSER_LEVEL:	// 超级用户添加管理员
			do_insert_user(ppDb,msg->name,msg->password,ADMIN_LEVEL);
			do_insert_user_info(ppDb,info_recv.name,info_recv.no,info_recv.addr,info_recv.age,info_recv.level,info_recv.phone,info_recv.salary);
		break;
		
		default:
		break;
	}
	
	return 0;
}

// 删除用户
// 参数1: 登录表
// 参数2: 要删除的用户名(由客户端提供)
// 参数3: 当前登录用户的权限
// 返回值: 成功0 失败-1
int do_del_user(sqlite3* ppDb, const char* name, int level)
{
	int ret = -1;
	
	debug("do_del_user.\n");
	debug("name: %s.\n", name);
	/* 要同时删除登录表和信息表 */
	switch (level) {
		case ADMIN_LEVEL:	// 管理员删除一个员工
		/* 校验当前level是不是有权限删除 */
			if (strcmp(name, "root") == 0) {
				return -1;
			}
			
			ret = do_sqlite_del(ppDb, name);
		
		break;
		
		case SUPERUSER_LEVEL:	// 超级用户删除管理员
		/* 不能删除自己 */
			if (strcmp(name, "root") == 0) {
				return -1;
			}
			
			ret = do_sqlite_del(ppDb, name);
		
		break;
		
		default:
		break;
	}
	
	return ret;
}

// 修改用户信息
// 参数1: 信息表
// 参数2: 登录表名
// 参数3: 连接后的描述符
// 参数4: 当前登录用户的权限
// 返回值: 成功0 失败-1
int do_alter_user(sqlite3* ppDb, const char* name, int accfd, int level)
{
	INFO info_recv;
	USER user_recv;
	int ret = -1;
	
	char **pazResult;
	int pnRow = 0;
	int pnColumn = 0;
	char *pzErrmsg;
	char buf[128] = {0};
	
	debug("do_alter_user.\n");
	
	/* 得到名字 */
	// 包括要修改的名字和密码
	 

	recv(accfd, &user_recv, sizeof(user_recv), 0);
	debug("user_recv.name: %s.\n", user_recv.name);
	
	recv(accfd, &info_recv, sizeof(info_recv), 0);
	debug("info_recv.name: %s.\n", info_recv.name);
	
	switch (level) {
		case USER_LEVEL:	// 用户修改自己的信息
			if (strcmp(user_recv.name, name) != 0) {
				return -1;
			} else {
				debug("USER_LEVEL\n");
				do_sqlite_alter(ppDb, &user_recv, &info_recv, USER_LEVEL);
			}
		/* 校验当前level是不是有权限修改 */
		break;
		
		case ADMIN_LEVEL:	// 管理员修改所有用户的信息
			sprintf(buf, "select * from log_in where name = '%s'", user_recv.name);
			sqlite3_get_table(ppDb, buf, &pazResult, &pnRow, &pnColumn, &pzErrmsg);
			if (atoi(pazResult[5]) > level) {
						return -1;
			} else {
				debug("ADMIN_LEVEL\n");
				do_sqlite_alter(ppDb, &user_recv, &info_recv, ADMIN_LEVEL);
			}
		break;
		
		case SUPERUSER_LEVEL:	// 超级用户修改全部
			debug("SUPERUSER_LEVEL\n");
			do_sqlite_alter(ppDb, &user_recv, &info_recv, SUPERUSER_LEVEL);
		break;
		
		default:
		break;
	}
	
	return 0;
}

// 查看信息
// 参数1: 信息表
// 参数2: 登录表名
// 参数3: 连接后的描述符
// 参数4: 当前登录用户的权限
// 返回值: 查询到的信息结构体

int do_user_query(sqlite3* ppDb, const char* table, int accfd, int level)

{

	int ret;
	INFO info_recv;
	INFO info_send;
	query_desc_t query_info;
	
	printf("do_user_query.\n");
	
	/* 得到名字 */
	recv(accfd, &info_recv, sizeof(info_recv), 0);
	printf("info_recv.name: %s\n", info_recv.name);


	ret = do_match_priv(ppDb,info_recv.name);//查看查询名字的等级
	if(ret == 0)
	{
		info_send.level = 0;
	}
	if(ret == 1)
	{
		info_send.level = 1;
	}
	if(ret == 2)
	{
		info_send.level = 2;
	}
	send(accfd,&info_send,sizeof(info_send),0);	//发送要查名字的等级


	
	switch (level) {
				case USER_LEVEL:	// 用户查看
					query_info = do_sqlite_query(ppDb,info_recv.name,USER_LEVEL);
					break;
				case  USER_QUERY_OTHER :
					query_info = do_sqlite_query(ppDb,info_recv.name,USER_QUERY_OTHER);
					break;
				case ADMIN_LEVEL:	// 管理员查询用户信息	
					query_info = do_sqlite_query(ppDb,info_recv.name,ADMIN_LEVEL);
					break;
		
				case SUPERUSER_LEVEL:	// 超级用户查询全部
					query_info = do_sqlite_query(ppDb,info_recv.name,SUPERUSER_LEVEL);
					break;
		
				default:
				break;
			}
	
	send(accfd,&query_info,sizeof(query_info),0);
	if(query_info.name[0] == 0) // not found
	{
		return -1;
	}

	return 1;
}
